package com.lechi.web.service.impl;

import com.lechi.iot.netty.utils.NettyCacheUtils;
import com.lechi.web.common.enums.ErrorCodeEnum;
import com.lechi.web.common.exception.ServiceException;
import com.lechi.web.constants.Constants;
import com.lechi.web.framework.log.IotExceptionLog;
import com.lechi.web.server.AppServer;
import com.lechi.web.server.WeatherServer;
import com.lechi.web.server.TcpServer;
import com.lechi.web.service.IIotGatewayService;
import com.lechi.web.system.domain.IotGatewayBo;
import com.lechi.web.system.mapper.iot.IotGatewayMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 网关类型Service业务层处理
 *
 * @author yangguang
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class IotGatewayServiceImpl implements IIotGatewayService {

    private final IotGatewayMapper iotGatewayMapper;

    /**
     * 查询网关类型
     *
     * @param name 网关类型主键
     * @return 网关类型
     */
    @Override
    public IotGatewayBo selectIotGatewayById(String name) {
        return iotGatewayMapper.selectIotGatewayByName(name);
    }

    /**
     * 查询网关类型列表
     *
     * @param iotGatewayBo 网关类型
     * @return 网关类型
     */
    @Override
    public List<IotGatewayBo> selectIotGatewayList(IotGatewayBo iotGatewayBo) {
        return iotGatewayMapper.selectIotGatewayList(iotGatewayBo);
    }

    /**
     * 新增网关类型
     *
     * @param iotGatewayBo 网关类型
     */
    @Override
    public void insertIotGateway(IotGatewayBo iotGatewayBo) {
        iotGatewayBo.setCreateTime(new Date());
        try {
            iotGatewayMapper.insertIotGateway(iotGatewayBo);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[1];
            String method = Thread.currentThread().getName() + ":" + stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
            CompletableFuture.runAsync(IotExceptionLog.exceptionLog(e, "新增网关类型", method, iotGatewayBo));
            throw new ServiceException(ErrorCodeEnum.ADD_ERROR.getValue(), ErrorCodeEnum.ADD_ERROR.getKey());
        }
    }

    /**
     * 修改网关类型
     *
     * @param iotGatewayBo 网关类型
     */
    @Override
    public void updateIotGateway(IotGatewayBo iotGatewayBo) {
        iotGatewayBo.setUpdateTime(new Date());
        try {
            iotGatewayMapper.updateIotGateway(iotGatewayBo);
        } catch (Exception e) {
            StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[1];
            String method = Thread.currentThread().getName() + ":" + stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
            CompletableFuture.runAsync(IotExceptionLog.exceptionLog(e, "修改网关类型", method, iotGatewayBo));
            throw new ServiceException(ErrorCodeEnum.EDIT_ERROR.getValue(), ErrorCodeEnum.EDIT_ERROR.getKey());
        }
    }

    @Override
    public void start(IotGatewayBo iotDevice) {
        int port = iotDevice.getPort() == 0 ? 18086 : iotDevice.getPort().intValue();
        int thread = iotDevice.getThread() == 0 ? 2 : iotDevice.getThread().intValue();
        int IDLE_TIMEOUT = 60000;
        int heartBeatTime = iotDevice.getHeartBeatTime() == 0 ? IDLE_TIMEOUT : iotDevice.getHeartBeatTime().intValue();
        if (Constants.MODBUS_RTU.equals(iotDevice.getGatewayName())) {
            TcpServer tcpServer = new TcpServer(port, thread, heartBeatTime, Constants.MODBUS_RTU);
            tcpServer.start();
            NettyCacheUtils.put(iotDevice.getGatewayName(), tcpServer);
        } else if (Constants.ANDROID_TCP.equals(iotDevice.getGatewayName())) {
            AppServer appServer = new AppServer(port, thread, heartBeatTime);
            appServer.start();
            NettyCacheUtils.put(Constants.ANDROID_TCP, appServer);
        } else {
            WeatherServer weatherServer = new WeatherServer(port, thread, heartBeatTime, iotDevice.getGatewayName());
            weatherServer.start();
            NettyCacheUtils.put(iotDevice.getGatewayName(), weatherServer);
        }
        log.error("已开启{} Socket服务: {}，占用端口：{}, 执行线程池线程数: {}",iotDevice.getGatewayName(), iotDevice.getGatewayName(), port, thread);
    }
}
